#include <string>
#include <iostream>

#include "pp_generator.h"
#include "pp_utils.h"

// c++17
#if __cplusplus >= 201703L
#include <filesystem>
namespace fs = std::filesystem;
#else
#include "pp_file.h"
namespace fs = pp;
#endif

void PrintUsage(const std::string& appname)
{
    std::cout << "Description: message generator." << std::endl
        << "Version: " << PP_GEN_VERSION << std::endl
        << "Usage: " << appname << " [-h] [-s DIRECTORY] [-d DIRECTORY]" << std::endl
        << "     [-l {c, cpp, java, oc, cs, js}]" << std::endl << std::endl
        << "optional arguments:" << std::endl
        << "  -h, --help\tShow this help information" << std::endl
        << "  -s DIRECTORY, --srcpath DIRECTORY" << std::endl
        << "\t\t\tSet protocol define file search directory" << std::endl
        << "  -l {c, cpp, java, oc, cs, js}, --language {c, cpp, java, oc, cs, js}" << std::endl
        << "\t\t\tMajor programming language you want to use, should be" << std::endl
        << "\t\t\t[c|cpp|java|oc|cs|js]" << std::endl
        << "  -d DIRECTORY, --directory DIRECTORY" << std::endl
        << "\t\t\tSet generate project directory for project" << std::endl
        << "Example:" << std::endl
        << "  " << appname << " --help" << std::endl
        << "  " << appname << " -s . -d ../test -l c" << std::endl;
}

int main(int argc, char* argv[])
{
    try
    {
        // 命令行参数
        std::string language = "cpp";
        std::string srcdir = "./";
        std::string destdir = "./";

        for (int i = 1; i < argc; i++)
        {
            std::string args = argv[i];

            M_GET_CMD_LINE(language, "-l", -1, PrintUsage, argv[0]);
            M_GET_CMD_LINE(language, "--language", -1, PrintUsage, argv[0]);
            M_GET_CMD_LINE(srcdir, "-s", -1, PrintUsage, argv[0]);
            M_GET_CMD_LINE(srcdir, "--srcpath", -1, PrintUsage, argv[0]);
            M_GET_CMD_LINE(destdir, "-d", -1, PrintUsage, argv[0]);
            M_GET_CMD_LINE(destdir, "--directory", -1, PrintUsage, argv[0]);

            if (args == "-h" || args == "--help")
            {
                PrintUsage(argv[0]);
                return 0;
            }
            if (args == "-v" || args == "--version")
            {
                std::cout << M_INFO_COLOR_START << "Version: " << PP_GEN_VERSION << M_INFO_COLOR_END << std::endl;
                return 0;
            }
        }

        if (fs::is_directory(srcdir))
        {
            pp::Generator gen(language, srcdir, destdir);
            for (const auto& entry : fs::recursive_directory_iterator(srcdir))
            {
                if (entry.is_regular_file() && entry.path().extension() == ".pp")
                {
                    std::cout << M_INFO_COLOR_START "GEN " << entry.path().c_str() << M_INFO_COLOR_END << std::endl;
                    gen.Generate(entry.path());
                }
            }
        }
        else if (fs::is_regular_file(srcdir))
        {
            pp::Generator gen(language, srcdir, destdir);
            std::cout << M_INFO_COLOR_START "GEN " << srcdir << M_INFO_COLOR_END << std::endl;
            gen.Generate(srcdir);
        }
        else
        {
            std::cerr << M_ERR_COLOR_START << "error: the given file or directory '" << srcdir
                << "' is not existed or invalid!" << M_ERR_COLOR_END << std::endl;
            return -1;
        }
    }
    catch(const std::exception& e)
    {
        std::cerr << M_ERR_COLOR_START "error: " << e.what() << M_ERR_COLOR_END << std::endl;
    }
    catch(...)
    {
        std::cerr << M_ERR_COLOR_START "error: unknown error" M_ERR_COLOR_END << std::endl;
    }

    return 0;
}
